import type { UserConfig } from 'vite';

import path, { relative, resolve } from 'node:path';

import dayjs from 'dayjs';
import { readPackageJSON } from 'pkg-types';
import { NodePackageImporter } from 'sass';
import { defineConfig, loadEnv, mergeConfig } from 'vite';

import { createPlugins } from '../plugins';
import { generateModifyVars } from '../utils/modifyVars';
import { commonConfig } from './common';

interface DefineOptions {
  overrides?: UserConfig;
  options?: object;
}

function defineApplicationConfig(defineOptions: DefineOptions = {}) {
  const { overrides = {} } = defineOptions;

  return defineConfig(async ({ command, mode }) => {
    const root = process.cwd();
    const isBuild = command === 'build';
    const { VITE_PUBLIC_PATH, VITE_NITRO_MOCK, VITE_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(mode, root);

    const defineData = await createDefineData(root);
    const plugins = await createPlugins({
      isBuild,
      root,
      enableAnalyze: VITE_ENABLE_ANALYZE === 'true',
      enableMock: VITE_NITRO_MOCK === 'true',
      compress: VITE_COMPRESS || 'none',
    });

    const pathResolve = (pathname: string) => resolve(root, '.', pathname);

    const applicationConfig: UserConfig = {
      base: VITE_PUBLIC_PATH,
      resolve: {
        alias: [
          {
            find: 'vue-i18n',
            replacement: 'vue-i18n/dist/vue-i18n.cjs.js',
          },
          // @/xxxx => src/xxxx
          {
            find: /@\//,
            replacement: `${pathResolve('src')}/`,
          },
          // #/xxxx => types/xxxx
          {
            find: /#\//,
            replacement: `${pathResolve('types')}/`,
          },
        ],
      },
      define: defineData,
      build: {
        target: 'esnext',
        cssTarget: 'chrome80',
        rollupOptions: {
          output: {
            // entryFileNames: 'assets/entry/[name]-[hash].js',
            assetFileNames: '[ext]/[name]-[hash].[ext]', // 资源文件（CSS、图片等）命名规则
            chunkFileNames: 'js/[name]-[hash].js', // 代码分割 chunk 命名规则
            entryFileNames: 'jse/index-[name]-[hash].js', // 入口文件命名规则
            // // 智能分包策略
            // manualChunks: (id) => {
            //   // 排除 node_modules 中的模块，优先使用自定义规则
            //   if (id.includes('node_modules')) {
            //     // Ant Design 组件库（必须在 Vue 之前检查，避免被 vue 匹配）
            //     if (id.includes('ant-design-vue')) {
            //       return 'antd';
            //     } else if (id.includes('@ant-design/icons-vue')) {
            //       return 'antd-icons';
            //     }
            //     // Vue 核心库（使用更精确的路径匹配）
            //     else if (id.includes('/vue/') || id.includes('/@vue/') || id.includes('/vue-router/')) {
            //       return 'vue';
            //     } else if (id.includes('/pinia/') || id.includes('/vue-i18n/')) {
            //       return 'pinia';
            //     }
            //     // VXE 表格组件
            //     else if (
            //       id.includes('vxe-table') ||
            //       id.includes('vxe-pc-ui') ||
            //       id.includes('vxe-table-plugin-export-xlsx')
            //     ) {
            //       return 'vxe';
            //     }
            //     // ECharts 图表库及其扩展
            //     else if (id.includes('echarts')) {
            //       return 'echarts';
            //     }
            //     // 富文本编辑器
            //     else if (id.includes('tinymce')) {
            //       return 'tinymce';
            //     } else if (id.includes('vditor')) {
            //       return 'vditor';
            //     } else if (id.includes('codemirror')) {
            //       return 'codemirror';
            //     }
            //     // 流程图组件
            //     else if (id.includes('@logicflow')) {
            //       return 'logicflow';
            //     }
            //     // Excel 处理库
            //     else if (id.includes('xlsx') || id.includes('exceljs')) {
            //       return 'excel';
            //     }
            //     // 工具库
            //     else if (id.includes('lodash-es')) {
            //       return 'lodash';
            //     } else if (id.includes('dayjs')) {
            //       return 'dayjs';
            //     } else if (id.includes('axios')) {
            //       return 'axios';
            //     } else if (id.includes('qs')) {
            //       return 'qs';
            //     } else if (id.includes('crypto-js') || id.includes('@zxcvbn-ts/core') || id.includes('secure-ls')) {
            //       return 'crypto';
            //     }
            //     // 其他大型库
            //     else if (id.includes('html2canvas') || id.includes('cropperjs') || id.includes('qrcode')) {
            //       return 'canvas';
            //     }
            //     // 其他 node_modules 模块不再统一打包，让 vite 自动分割以避免单个文件过大
            //     // return 'vendor';
            //   }
            //   // 对于业务代码，根据路径进行分组
            //   // 将 views 目录下的大型页面独立打包
            //   // 提取目录名作为 chunk 名称
            //   else if (id.includes('/src/views/') && !id.includes('/packages/eacloud/kanban/')) {
            //     if (id.includes('/src/views/report/')) {
            //       if (id.includes('/src/views/report/report/')) {
            //         if (id.includes('/src/views/report/report/kanban/')) {
            //           // 提取目录名作为 chunk 名称
            //           const match = id.match(/\/src\/views\/report\/report\/kanban\/([^/]+)/);
            //           if (match && match[1]) {
            //             return `pages-report-rpt-kanban-${match[1]}`;
            //           }
            //         } else {
            //           // 提取目录名作为 chunk 名称
            //           const match = id.match(/\/src\/views\/report\/report\/([^/]+)/);
            //           if (match && match[1]) {
            //             return `pages-report-rpt-${match[1]}`;
            //           }
            //         }
            //       } else {
            //         // 提取目录名作为 chunk 名称
            //         const match = id.match(/\/src\/views\/report\/([^/]+)/);
            //         if (match && match[1]) {
            //           return `pages-report-${match[1]}`;
            //         }
            //       }
            //     } else {
            //       // 提取目录名作为 chunk 名称
            //       const match = id.match(/\/src\/views\/([^/]+)/);
            //       if (match && match[1]) {
            //         return `pages-${match[1]}`;
            //       }
            //     }
            //   }
            //   // 将 components 目录下的组件分组
            //   else if (id.includes('/src/components/') && !id.includes('/packages/eacloud/kanban/')) {
            //     // 提取目录名作为 chunk 名称
            //     const match = id.match(/\/src\/components\/([^/]+)/);
            //     if (match && match[1]) {
            //       return `components-${match[1]}`;
            //     }
            //   }
            // },
            // 将大型库分离到独立 chunk
            manualChunks: {
              // Vue 核心库
              vue: ['vue', 'vue-router'],
              pinia: ['pinia', 'pinia-plugin-persistedstate'],
              // UI 组件库 - 分离成多个 chunk 避免单个过大
              antd: ['ant-design-vue'],
              'antd-icons': ['@ant-design/icons-vue'],
              vxe: ['vxe-table', 'vxe-pc-ui', 'vxe-table-plugin-export-xlsx'],
              // 大型工具库
              echarts: ['echarts'],
              // 富文本编辑器 - 这些库通常很大
              tinymce: ['tinymce'],
              // vditor: ['vditor'],
              codemirror: ['codemirror'],
              // 流程图库
              // logicflow: ['@logicflow/core', '@logicflow/extension'],
              // 其他工具库
              utils: ['lodash-es', 'dayjs', 'axios'],
              qs: ['qs'],
              'xe-utils': ['xe-utils'],
              excel: ['exceljs', 'xlsx'],
              canvas: ['html2canvas', 'cropperjs', 'qrcode'],
            },
          },
        },
      },
      css: {
        preprocessorOptions: {
          less: {
            modifyVars: generateModifyVars(),
            javascriptEnabled: true,
          },
          scss: {
            // 把sass即将弃用的js-api和颜色函数警告去掉
            // silenceDeprecations: ['legacy-js-api', 'color-functions'],
            additionalData: (content: string, filepath: string) => {
              const relativePath = relative(root, filepath);
              // src目录下注入全局样式
              if (relativePath.startsWith(`src${path.sep}`)) {
                // console.log('additionalData', { content, filepath, root, relativePath });
                return `@use "@vben/styles/global" as *;@use "@/design/config" as *;\n${content}`;
              }
              return content;
            },
            api: 'modern',
            importers: [new NodePackageImporter()],
          },
        },
      },
      plugins,
    };

    const mergedConfig = mergeConfig(commonConfig(mode), applicationConfig);

    return mergeConfig(mergedConfig, overrides);
  });
}

async function createDefineData(root: string) {
  try {
    const pkgJson = await readPackageJSON(root);
    const { dependencies, devDependencies, name, version } = pkgJson;

    const __APP_INFO__ = {
      pkg: { dependencies, devDependencies, name, version },
      lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
    };
    return {
      __APP_INFO__: JSON.stringify(__APP_INFO__),
    };
  } catch (error) {
    console.error(error);
    return {};
  }
}

export { defineApplicationConfig };
